// XInput.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "XInput.h"
#include <OpenGL\freeglut.h>

XButton* buttons;
XMouse* mouse;


	//X BUTTON//

XButton::XButton()
{
	CurrentState = false;
	PreviousState = false;
}

bool XButton::GetCurrent()
{
	return CurrentState;
}

bool XButton::GetPrevious()
{
	return PreviousState;
}

void XButton::SetPressed()
{
	CurrentState = true;
}

void XButton::SetReleased()
{
	CurrentState = false;
}

void XButton::Update()
{
	PreviousState = CurrentState;
}


	//X MOUSE//

XMouse::XMouse()
{

}

void XMouse::SetPosition(int x, int y)
{
	Position.X = x;
	Position.Y = y;
}

XPosition XMouse::GetPosition()
{
	return Position;
}

XButton XMouse::GetLeft()
{
	return LeftButton;
}

XButton XMouse::GetRight()
{
	return RightButton;
}

XButton XMouse::GetMiddle()
{
	return MiddleButton;
}

XButton XMouse::GetWheelUp()
{
	return WheelUp;
}

XButton XMouse::GetWheelDown()
{
	return WheelDown;
}

void XMouse::Update()
{
	LeftButton.Update();
	RightButton.Update();
	MiddleButton.Update();
	WheelUp.Update();
	WheelDown.Update();
}


	//X INPUT MODULE//

XInputModule::XInputModule()
{

}

XButton XInputModule::GetButton(int button)
{
	return Button[button];
}

XMouse XInputModule::GetMouse()
{
	return Mouse;
}

void XInputModule::Initialize()
{
	glutKeyboardFunc(_keyboard);
	glutKeyboardUpFunc(_keyboardUp);
	glutSpecialFunc(_special);
	glutSpecialUpFunc(_specialUp);
	glutMouseWheelFunc(_mouseWheel);
	glutMouseFunc(_mouse);
	glutPassiveMotionFunc(_motion);
	glutMotionFunc(_motion);

	buttons = Button;
	mouse = &Mouse;
}

void XInputModule::PreUpdate()
{
	Mouse.WheelDown.SetReleased();
	Mouse.WheelUp.SetReleased();
}

void XInputModule::PostUpdate()
{
	Mouse.Update();

	for(int i=0; i<149; i++)
		Button[i].Update();
}

void XInputModule::Exit()
{

}

void XInputModule::_keyboard(unsigned char key, int x, int y)
{
	buttons[key].SetPressed();
	mouse->SetPosition(x, y);

}

void XInputModule::_keyboardUp(unsigned char key, int x, int y)
{
	buttons[key].SetReleased();

	if(key >97 && key < 122)
		buttons[key+32].SetReleased();

	mouse->SetPosition(x, y);
}

void XInputModule::_special(int key, int x, int y)
{
	mouse->SetPosition(x, y);

	switch(key)
	{
	case GLUT_KEY_F1:
		buttons[XKEY_F1].SetPressed();
		break;

	case GLUT_KEY_F2:
		buttons[XKEY_F2].SetPressed();
		break;

	case GLUT_KEY_F3:
		buttons[XKEY_F3].SetPressed();
		break;

	case GLUT_KEY_F4:
		buttons[XKEY_F4].SetPressed();
		break;

	case GLUT_KEY_F5:
		buttons[XKEY_F5].SetPressed();
		break;

	case GLUT_KEY_F6:
		buttons[XKEY_F6].SetPressed();
		break;

	case GLUT_KEY_F7:
		buttons[XKEY_F7].SetPressed();
		break;

	case GLUT_KEY_F8:
		buttons[XKEY_F8].SetPressed();
		break;

	case GLUT_KEY_F9:
		buttons[XKEY_F9].SetPressed();
		break;

	case GLUT_KEY_F10:
		buttons[XKEY_F10].SetPressed();
		break;

	case GLUT_KEY_F11:
		buttons[XKEY_F11].SetPressed();
		break;

	case GLUT_KEY_F12:
		buttons[XKEY_F12].SetPressed();
		break;

	case GLUT_KEY_LEFT:
		buttons[XKEY_LEFT].SetPressed();
		break;

	case GLUT_KEY_UP:
		buttons[XKEY_UP].SetPressed();
		break;

	case GLUT_KEY_RIGHT:
		buttons[XKEY_RIGHT].SetPressed();
		break;

	case GLUT_KEY_DOWN:
		buttons[XKEY_DOWN].SetPressed();
		break;

	case GLUT_KEY_PAGE_UP:
		buttons[XKEY_PAGE_UP].SetPressed();
		break;

	case GLUT_KEY_PAGE_DOWN:
		buttons[XKEY_PAGE_DOWN].SetPressed();
		break;

	case GLUT_KEY_HOME:
		buttons[XKEY_HOME].SetPressed();
		break;

	case GLUT_KEY_END:
		buttons[XKEY_END].SetPressed();
		break;

	case GLUT_KEY_INSERT:
		buttons[XKEY_INSERT].SetPressed();
		break;
	}
}

void XInputModule::_specialUp(int key, int x, int y)
{
	mouse->SetPosition(x, y);

	switch(key)
	{
	case GLUT_KEY_F1:
		buttons[XKEY_F1].SetReleased();
		break;

	case GLUT_KEY_F2:
		buttons[XKEY_F2].SetReleased();
		break;

	case GLUT_KEY_F3:
		buttons[XKEY_F3].SetReleased();
		break;

	case GLUT_KEY_F4:
		buttons[XKEY_F4].SetReleased();
		break;

	case GLUT_KEY_F5:
		buttons[XKEY_F5].SetReleased();
		break;

	case GLUT_KEY_F6:
		buttons[XKEY_F6].SetReleased();
		break;

	case GLUT_KEY_F7:
		buttons[XKEY_F7].SetReleased();
		break;

	case GLUT_KEY_F8:
		buttons[XKEY_F8].SetReleased();
		break;

	case GLUT_KEY_F9:
		buttons[XKEY_F9].SetReleased();
		break;

	case GLUT_KEY_F10:
		buttons[XKEY_F10].SetReleased();
		break;

	case GLUT_KEY_F11:
		buttons[XKEY_F11].SetReleased();
		break;

	case GLUT_KEY_F12:
		buttons[XKEY_F12].SetReleased();
		break;

	case GLUT_KEY_LEFT:
		buttons[XKEY_LEFT].SetReleased();
		break;

	case GLUT_KEY_UP:
		buttons[XKEY_UP].SetReleased();
		break;

	case GLUT_KEY_RIGHT:
		buttons[XKEY_RIGHT].SetReleased();
		break;

	case GLUT_KEY_DOWN:
		buttons[XKEY_DOWN].SetReleased();
		break;

	case GLUT_KEY_PAGE_UP:
		buttons[XKEY_PAGE_UP].SetReleased();
		break;

	case GLUT_KEY_PAGE_DOWN:
		buttons[XKEY_PAGE_DOWN].SetReleased();
		break;

	case GLUT_KEY_HOME:
		buttons[XKEY_HOME].SetReleased();
		break;

	case GLUT_KEY_END:
		buttons[XKEY_END].SetReleased();
		break;

	case GLUT_KEY_INSERT:
		buttons[XKEY_INSERT].SetReleased();
		break;
	}
}

void XInputModule::_mouseWheel(int button, int direction, int x, int y)
{
	mouse->SetPosition(x, y);

	if (direction > 0)
	{
		mouse->WheelUp.SetPressed();
		mouse->WheelDown.SetReleased();
	}
    else if(direction < 0)
	{
		mouse->WheelUp.SetReleased();
		mouse->WheelDown.SetPressed();
	}
	else
	{
		mouse->WheelDown.SetReleased();
		mouse->WheelUp.SetReleased();
	}
}

void XInputModule::_mouse(int button, int state, int x, int y)
{
	mouse->SetPosition(x, y);

	if(state == GLUT_DOWN)
	{
		if(button == GLUT_LEFT_BUTTON)
			mouse->LeftButton.SetPressed();
		
		else if (button == GLUT_MIDDLE_BUTTON)
			mouse->MiddleButton.SetPressed();
		
		else if (button == GLUT_RIGHT_BUTTON)
			mouse->RightButton.SetPressed();
	}
	else if(state == GLUT_UP)
	{
		if(button == GLUT_LEFT_BUTTON)
			mouse->LeftButton.SetReleased();

		else if (button == GLUT_MIDDLE_BUTTON)
			mouse->MiddleButton.SetReleased();
		
		else if (button == GLUT_RIGHT_BUTTON)
			mouse->RightButton.SetReleased();
	}
}

void XInputModule::_motion(int x, int y)
{
	mouse->SetPosition(x, y);
}